package gui.clock;

import java.awt.event.ActionEvent;
import gui.EarthPanel;
import javax.swing.JOptionPane;

import simulation.SimEngine;

public class ClockControl extends AbstractClock {
  private static final long serialVersionUID = -5822023900023271362L;
  
  private EarthPanel pnlEarth;
  private ClockDisplay clockDisplay;
  private long elapsedTime = 0;
  private long duration;
  protected SimEngine engine;
  private int intervalCounter = 0;
  private int interval = 0;
  
  public ClockControl(EarthPanel pnlEarth, ClockDisplay clockDisplay) {
    super();
    this.pnlEarth = pnlEarth;
    this.clockDisplay = clockDisplay;
    this.engine = new SimEngine(settings.getEccentricity(), 
    settings.getTilt(), 
    settings.getGridSpacing(), 
    settings.getRadius());
  }
  
  public void setDateTime(long dateTime) {
//    pnlDateTime.setDateTime(dateTime);
    engine.setDateTime(dateTime);
  }
  
  public void start() {
    if(!settings.isQueryRunning()) {
      engine.setEccentricity(settings.getEccentricity());
      engine.setTiltOfEarth(settings.getTilt());
      engine.setSimTimeStep(settings.getTimeStep());
      engine.setGridSpacing(settings.getGridSpacing(), pnlEarth.getRadius());
      engine.setDateTime(settings.getStartDateTime());
      setSimTimeStep(settings.getTimeStep());
      duration = settings.getEndDateTime() - settings.getStartDateTime();
      
      //compute temporal accuracy
      long stepsToTake = duration / simTimeStep;
      double stepsToSkip = stepsToTake * settings.getTemporalAccuracy() / 100;
      interval = (int) Math.ceil(stepsToTake / stepsToSkip) - 1;
    }
    dateTimeClock.start();    
  }
  
  public void pause() {
    dateTimeClock.stop();    
  }
  
  public void reset() {
    dateTimeClock.stop();
    clockDisplay.reset();
    pnlEarth.reset();
    engine.reset();
    settings.reset();
    elapsedTime = 0;
    intervalCounter = 0;
  }
  
  public void actionPerformed(ActionEvent e) {
    elapsedTime += simTimeStep;
    if (elapsedTime >= duration) {
      pause();
      if(elapsedTime > duration) {
        elapsedTime -= simTimeStep;
        JOptionPane.showMessageDialog(
          clockDisplay, 
          "Lower your time step to complete the simulation.",
          "Incomplete Simulation...",
          JOptionPane.INFORMATION_MESSAGE);
        settings.resetRunButton();
      }
      else {
        //simulation complete after this step
        step();
        settings.finalStep();
      }
    }
    else {      
      step();      
    }    
  }
  
  private void step() {
    engine.step();
    
    if(settings.isAnimation()) {
      pnlEarth.updateGrid(engine.getGrid());
      pnlEarth.moveSunPosition(sunDegStep);
      clockDisplay.increment(simTimeStep);
    }
//System.out.println("clock display time: "+clockDisplay.getTime()+ "    time step: "+simTimeStep);
    settings.cacheGrid(engine.getGrid());
  }
  
}
